# 1. 抽取每张图的每个模型的评分（20个指标的），到以图为单位
# 2. 将1中的汇总，即一张图只有35个数据。如何压缩呢？
# 在图1对应的数据表中
# 指标换算，如sen指标，将该指标的全局最大值设为1，将全局指标最小值设为0.
# 然后，把DDcGAN模型的20个指标全部换成0-1之间
# 把DDcGAN关于图1的20个指标加起来，就是DDcGAN关于图1的得分
# 最后，得到一张115*35大小的图，115是图编号，35是模型数。
# 3. 最后，生成一个result.xlsx文件。


# 1.使用extractAndCmp完成
# 2.指标的一行压缩为一个数
import json
import openpyxl, os, math

# 文件的位置
# data_path = "../../data"        # 这个里面是json文件
# file_name = "./picByNo.xlsx"  这个用不到了！
result_path = "./result.xlsx"

# 列名
metrics = ['sen', 'me', 'mse(small)', 'avg', 'std', 'vifp', 'snr', 'min', 'uqi', 'qabf', 'vif', 'ssim',
           'psnr', 'ifc', 'q0i', 'ce(small)', 'edge', 'qcv(small)', 'sf', 'qcb']


def writeXlsx(sheetData, result_path):
    "将表单数据写到path文件中"
    new_wb = openpyxl.Workbook()  # 创建新表
    new_sheet = new_wb.create_sheet(title="figureData")
    # 添加到表中
    for row in sheetData:
        new_sheet.append(row)  # 首先插入第一行列名，横坐标
    new_wb.save(result_path)  # 写入,保存为模型名
    print("%s保存成功！" % result_path)


def getAllData():
    "获取一个目录下所有json的数据 data={modelName:[{row1},{row2}]}"
    dir = "../../data"  # 获取所有模型的数据，json格式
    filenames = os.listdir(dir)

    get_name = lambda x: x.split('.')[0]  # 获得json文件名

    data = {}
    for file in filenames:  # 读取每个文件
        with open(os.path.join(dir, file), "r", encoding="utf8") as f:
            data[get_name(file)] = json.loads(f.read())
    return data


def getMaxMin(data):
    "data是总表，获取data中每个指标的最大值和最小值"
    # 首先定义一个初始值
    poleNum = {key: [math.inf, -math.inf] for key in metrics}
    # data: modelName:[{row1},{row2}]
    for modelName, tableData in data.items():
        for row in tableData:
            for k, v in row.items():
                poleNum[k] = [min(poleNum[k][0], v), max(poleNum[k][1], v)]
    return poleNum


def setToZeroOne(data, poleNum):
    "将data中的数据规整到0~1"

    def get01(num, min, max, reverse=False):
        "将num规整"
        regularateNum = (num - min) / (max - min)
        return regularateNum if not poleNum else 1 - regularateNum

    # 将每个数据归一化
    for modelName, tableData in data.items():
        for row in tableData:
            for k, v in row.items():
                row[k] = get01(v, *poleNum[k], "small" not in k)


def getFinalData(data, mtxsWanted):
    "行为图片标号，列为模型名，中间是每个模型的图片指标值"
    rowX = [[str(i)] for i in range(1, 116)]  # 行*列
    # 添加数据
    for modelName, tableData in data.items():
        for i, row in enumerate(tableData):
            score = 0.0
            for k, v in row.items():  # xlsx中一行是一个图片的20个指标
                for lev,wgt in enumerate([1.5, 1.4, 1.3, 1.2, 1.0, 0.8, 0.7, 0.6, 0.5, 0.4]):
                    if k in mtxsWanted[lev]:
                        score += wgt * v
                        break
            rowX[i].append(score)
    # 加上表名
    headline = [name.split(".")[0] for name in data.keys()]
    headline.insert(0, "picNo")

    rowX.insert(0, headline)
    return rowX


# 先查到每个指标的最大最小值
# 然后指标换算，放到另一个xlsx中
if __name__ == '__main__':
    data = getAllData()
    poleNum = getMaxMin(data)
    setToZeroOne(data, poleNum)
    # 这儿插入个评价指标,并且进行了分级展示
    # mtxsWanted = metrics
    # mtxsWanted = [['sen','me','edge','qcv(small)','qcb'],['std','uqi','ce(small)','sf'],['qabf','psnr','ifc'],['avg','vifp','vif']]
    mtxsWanted = [
        ['me'],
        ['edge'],
        ['qcv(small)', 'qcb'],
        ['sen'],
        ['ce(small)'],
        ['uqi'],
        ['std', 'sf'],
        ['qabf', 'psnr', 'ifc'],
        ['avg', 'vif'],
        ['vifp']
    ]

    final_data = getFinalData(data, mtxsWanted)
    writeXlsx(final_data, result_path)
